/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.softcomputo.decodificador.util;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;

import com.softcomputo.decodificador.DicomReaderH;

/**
 *
 * @author Luis Miguel Hernández Pérez
 */
public class DecodificadorUtils {

    public static Image escalarImagen(int n, int heigth, int width, byte[] pixeles, boolean indicado, int bitsAlmacenados, int highBit, boolean ignorarValoresNegativos) {
        ColorModel cm = modeloColorGris();
        int scaledWidth = width / 2;
        int scaledHeight = heigth / 2;
        int index = 0;
        int value = 0;
        byte[] destPixels = null;
        System.gc();


        if (n == 1) {
            destPixels = new byte[scaledWidth * scaledHeight];
            for (int i = 0; i < heigth; i += 2) {
                for (int j = 0; j < width; j += 2) {
                    destPixels[index++] = pixeles[(i * width) + j];
                }
            }
            pixeles = null;

            return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width / 2, heigth / 2, cm, destPixels, 0, width / 2));
        } else if (n == 2 && bitsAlmacenados <= 8) {
            destPixels = new byte[width * heigth];
            int len = width * heigth;
            for (int i = 0; i < len; i++) {
                value = (int) (pixeles[i * 2]) & 0xff;
                destPixels[i] = (byte) value;

            }
            pixeles = null;
            return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, heigth, cm, destPixels, 0, width));

        } else if (!indicado) {
            int[] intPixels = new int[scaledWidth * scaledHeight];
            int maxValue = 0;
            int minValue = 0xffff;
            if (highBit >= 8) {
                for (int i = 0; i < heigth; i += 2) {
                    for (int j = 0; j < width; j += 2) {
                        value = ((int) (pixeles[(2 * (i * width + j)) + 1] & 0xff) << 8) | (int) (pixeles[2 * (i * width + j)] & 0xff);
                        if (value > maxValue) {
                            maxValue = value;
                        }
                        if (value < minValue) {
                            minValue = value;
                        }
                        intPixels[index++] = value;
                    }
                }

            }
            int scale = maxValue - minValue;
            if (scale == 0) {
                scale = 1;
            }
            pixeles = null;
            destPixels = new byte[scaledWidth * scaledHeight];
            for (int i = 0; i < intPixels.length; i++) {
                value = (intPixels[i] - minValue) * 256;
                value /= scale;
                destPixels[i] = (byte) (value & 0xff);
            }
            intPixels = null;
            return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width / 2, heigth / 2, cm, destPixels, 0, width / 2));
        } else if (indicado) {
            byte[] pixels = indicadoTo8PerPix(pixeles, width, heigth, highBit, ignorarValoresNegativos);
            pixeles = pixels;
            for (int i = 0; i < heigth; i += 2) {
                for (int j = 0; j < width; j += 2) {
//                    destPixels[index++] = pixeles[(i * width) + j];
                }
            }
            pixeles = null;
            return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width / 2, heigth / 2, cm, destPixels, 0, width / 2));
        }
        return null;
    }

    public static ColorModel modeloColorGris() {
        byte[] r = new byte[256];
        for (int i = 0; i < 256; i++) {
            r[i] = (byte) (i & 0xff);
        }
        return (new IndexColorModel(8, 256, r, r, r));
    }

    public static byte[] indicadoTo8PerPix(byte[] pixData, int width, int heigth, int highbit, boolean ignorarValoresNegativos) {
        int[] pixels = new int[width * heigth];
        short shValue = 0;
        int value = 0;
        if (highbit >= 8) {
            for (int i = 0; i < pixels.length; i++) {
                shValue = (short) (((pixData[(2 * i) + 1] & 0xff) << 8) | (pixData[(2 * i)] & 0xff));//msb first !
                value = (int) shValue;
                if (value < 0 && ignorarValoresNegativos) {
                    value = 0;
                }
                pixels[i] = value;
            }
        }
        if (highbit <= 7) {
            for (int i = 0; i < pixels.length; i++) {
                shValue = (short) (((pixData[(2 * i) + 1] & 0xff) << 8) | (pixData[(2 * i)] & 0xff));//msb first !
                value = (int) shValue;
                if (value < 0 && ignorarValoresNegativos) {
                    value = 0;
                }
                pixels[i] = value;
            }
        }
        int maxValue = 0;
        int minValue = 0xffff;
        for (int i = 0; i < pixels.length; i++) {
            if (pixels[i] > maxValue) {
                maxValue = pixels[i];
            }
            if (pixels[i] < minValue) {
                minValue = pixels[i];
            }

        }
        byte[] destPixels = new byte[width * heigth];
        int scale = maxValue - minValue;
        if (scale == 0) {
            scale = 1;
            //System.Out.Println(" Error in VR form SignedTo8..DicomReader");
        }
        for (int i = 0; i < pixels.length; i++) {
            value = ((pixels[i] - minValue) * 255) / scale;
            destPixels[i] = (byte) (value & 0xff);
        }
        return destPixels;
    }

    public static byte[] to8PerPix(byte[] pixData, int width, int heigth, int bitsAlmacenamiento, int highBit) {
        if (bitsAlmacenamiento <= 8) {

            byte[] destPixels = new byte[width * heigth];
            int len = width * heigth;
            int value = 0;
            for (int i = 0; i < len; i++) {
                value = (int) (pixData[i * 2]) & 0xff;
                destPixels[i] = (byte) value;
            }
            return destPixels;
        }//

        int[] pixels = new int[width * heigth];
        int value = 0;
        if (highBit >= 8) {

            for (int i = 0; i < pixels.length; i++) {
                value = ((int) (pixData[(2 * i) + 1] & 0xff) << 8) | (int) (pixData[(2 * i)] & 0xff);//msb first !
                pixels[i] = value;
            }
        } else if (highBit <= 7) {

            for (int i = 0; i < pixels.length; i++) {
                value = ((int) (pixData[(2 * i)] & 0xff) << 8) | (int) (pixData[(2 * i) + 1] & 0xff);//lsb first !
                pixels[i] = value;
            }
        }

        int maxValue = 0;
        int minValue = 0xffff;
        for (int i = 0; i < pixels.length; i++) {
            if (pixels[i] > maxValue) {
                maxValue = pixels[i];
            }
            if (pixels[i] < minValue) {
                minValue = pixels[i];
            }
        }

        int scale = maxValue - minValue;
        if (scale == 0) {
            scale = 1;
        }
        byte[] destPixels = new byte[width * heigth];
        for (int i = 0; i < pixels.length; i++) {
            value = ((pixels[i] - minValue) * 255) / scale;
            destPixels[i] = (byte) (value & 0xff);

        }

        return destPixels;

    }

    public static boolean isIndicado(DicomReaderH dicomReaderH) {
        return dicomReaderH.getPixelRepresentacion() == 1;
    }

    public static BufferedImage toBufferedImage(Image img) {
        int width = img.getWidth(null);
        int heigth = img.getHeight(null);
        // creamos un buffer con trasparencia
        BufferedImage bimage = new BufferedImage(width, heigth, BufferedImage.TYPE_INT_ARGB);
        // Dibujamos la imagen en el buffer de imagen
        Graphics2D bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, width, heigth, null);
        bGr.dispose();
        // retornamos el buffer de imagenes
        return bimage;
    }
}
